//
// Created by tan on 16-10-29.
//

#include <Entities/plant.h>
#include "typeEnergy.h"
using namespace std;

namespace skill {
    bool Produce::use(Game *g, const std::vector<std::string> &params) {
        if (!Skill::use(g, params)) return false;
        double energy = std::stoi(origin->properties["energy"]);
        double produceRate = std::stoi(origin->properties["efficiency"]);
        Actor *originActor = dynamic_cast<Actor *>(origin);
		double energyGain =  produceRate * std::stod(params[0]);
		energy = energy + energyGain;
        origin->properties["energy"] = std::to_string((int) energy);
        return true;
    }

    bool ProduceManage::use(Game *g, const std::vector<std::string> &params) {
        map<Point, int> gridEntityCount;
        map<Point, int> minRange;

        for (int i = 0; i < MAP_SIZE; ++ i)
            for (int j = 0; j < MAP_SIZE; ++ j) {
                Point to_pos = Point(i, j);
                minRange[to_pos] = GatherRange;
                gridEntityCount[to_pos] = 0;
            }

        for (auto it: g->entityManager.entityList){
            auto entity = dynamic_cast<entity::Plant*>(it.second);
            if (entity == nullptr) continue;
            if (entity->properties["dead"] == "true") continue;
            if (!entity->hasSkill("Produce")) continue;
            Point pos = entity->pos();
            for (int i = 0; i < MAP_SIZE; ++ i)
                for (int j = 0; j < MAP_SIZE; ++ j){
                    Point to_pos = Point(i, j);
                    int range = getSquaredEuclideanDist(pos, to_pos);
                    if (range < minRange[to_pos]){
                        minRange[to_pos] = range;
                        gridEntityCount[to_pos] = 1;
                    }
                    else if (range == minRange[to_pos]){
                        ++ gridEntityCount[to_pos];
                    }
                }
        }
        for (auto it: g->entityManager.entityList){
            auto entity = dynamic_cast<entity::Plant*>(it.second);
            if (entity == nullptr) continue;
            if (entity->properties["dead"] == "true") continue;
            if (!entity->hasSkill("Produce")) continue;
            Point pos = entity->pos();
            double total = 0;
            for (int i = 0; i < MAP_SIZE; ++ i)
                for (int j = 0; j < MAP_SIZE; ++ j){
                    Point to_pos = Point(i, j);
                    int range = getSquaredEuclideanDist(pos, to_pos);
                    if (range == minRange[to_pos]){
                        total += g->terrain.energy[i][j] / gridEntityCount[to_pos];
                    }
                }
            entity->useSkill("Produce", {to_string(total)});
        }
        return Skill::use(g, params);
    }
}